﻿using System;
using System.Linq;
using System.ComponentModel.Composition;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.ArchitectureTools.CodeRepositoryQuery;
using UCL.Powersource.Analysis;
using System.Diagnostics.CodeAnalysis;

namespace UCL.Powersource.Statistics
{
    /// <summary>
    /// Class for calculation of the number of methods defined in the classes of the indexed assemblies
    /// </summary>
    [Export(typeof(IStatistic))]
    [DataContract(IsReference = true)]
    public class NumberOfMethodsStats : StatisticTeamBase
    {
        [ExcludeFromCodeCoverage]
        public override string Label
        {
            get { return "Number of methods"; }
        }

        [ExcludeFromCodeCoverage]
        public override string Description
        {
            get { return "Number of methods defined in the classes of the indexed assemblies"; }
        }

        [ExcludeFromCodeCoverage]
        public override string Name
        {
            get { return "NumberOfMethodsStats"; }
        }

        public static readonly Guid CN_Statistic_Guid = new Guid("421ACB2C-6C3D-4858-9BE5-1A18494C470E");
        [ExcludeFromCodeCoverage]
        public override Guid Statistic_Guid
        {
            get { return CN_Statistic_Guid; }
        }

        [DataMember]
        private string _FormatString = "0";

        public override string FormatString
        {
            get
            {
                return _FormatString;
            }
        }

   
        /// <summary>
        /// Class for tfs stat project configuration and time frame calculation
        /// </summary>
        /// <param name="teamProjConfig">Tfs stat project collection</param>
        /// <param name="timeFrame">Iteration time frame</param>
        /// <returns>Number of methods</returns>
        protected override double? CalculateFor(ITfsTeamProjectConfiguration teamProjConfig, ITimeFrame timeFrame)
        {
            int numberOfMethods = 0;

            var analysisBridge = teamProjConfig.ProjectAnalysisBridge;
            var codeIndex = analysisBridge.RetrieveCodeIndex(timeFrame);             

            // We won't modify the code index.
            codeIndex.Assemblies.MergeOption =          System.Data.Objects.MergeOption.NoTracking;
            codeIndex.AssemblyReferences.MergeOption =  System.Data.Objects.MergeOption.NoTracking;
            codeIndex.Namespaces.MergeOption =          System.Data.Objects.MergeOption.NoTracking;
            codeIndex.Types.MergeOption =               System.Data.Objects.MergeOption.NoTracking;
            codeIndex.TypeDefinitions.MergeOption =     System.Data.Objects.MergeOption.NoTracking;
            codeIndex.MethodDefinitions.MergeOption =   System.Data.Objects.MergeOption.NoTracking;
            codeIndex.Fields.MergeOption =              System.Data.Objects.MergeOption.NoTracking;
            codeIndex.Properties.MergeOption =          System.Data.Objects.MergeOption.NoTracking;
            codeIndex.Events.MergeOption =              System.Data.Objects.MergeOption.NoTracking;

            numberOfMethods = 
                codeIndex.MethodDefinitions.Count(m => !m.IsRuntimeSpecialName && !m.IsToolSpecialName);

            return numberOfMethods;
        }

        public override bool RequiresBuild
        {
            get { return true; }
        }
    }
}
